﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace IQReportes_Batch
{
    class CrearBD
    {
        private FuncionesGenericas funciones = new FuncionesGenericas();
        private List<DIR> listaDIR = new List<DIR>();//dato inicial

        private List<TipoTransaccion> listaTipos = new List<TipoTransaccion>();//dato inicial
        private List<EstadoTransaccion> listaEstados = new List<EstadoTransaccion>();
        
        private DirDAO dbDIR = new DirDAO();
        private EstadoTransaccionDAO dbEstado = new EstadoTransaccionDAO();
        private TipoTransaccionDAO dbTipoTransaccion = new TipoTransaccionDAO();

        private void obtenerDatosIniciales()
        {
            listaDIR = dbDIR.dirs.ToList();
            listaEstados = dbEstado.estados.ToList();
        }

        private DateTime calcularFechaXantiguedad(DateTime fecha, int antiguedad, string tabla)
        {
            int diasAtras;
            if (Constantes.IBK_TBL_CONS_ANO.Equals(tabla))
            {
                diasAtras = -365 * antiguedad;
                //return funciones.calcularAno(fecha.AddDays(diasAtras)).ToString();
            }
            else if (Constantes.IBK_TBL_CONS_MES.Equals(tabla))
            {
                diasAtras = 0;
                DateTime fechaAct = fecha;
                for (int i = 1; i <= antiguedad; i++)
                {
                    if (fechaAct.Month == 3 && fechaAct.Day <= 2)
                    {
                        diasAtras = diasAtras - 28;
                        fechaAct = fechaAct.AddDays(-28);
                    }
                    else if (fechaAct.Day >= 30)
                    {
                        diasAtras = diasAtras - 33;
                        fechaAct = fechaAct.AddDays(-33);
                    }
                    else
                    {
                        diasAtras = diasAtras - 30;
                        fechaAct = fechaAct.AddDays(-30);
                    }
                }
                //return funciones.calcularMes(fecha.AddDays(diasAtras));
            }
            else if (Constantes.IBK_TBL_CONS_SEMANA.Equals(tabla))
            {
                diasAtras = -7 * antiguedad;
                //return funciones.calcularSemana(fecha.AddDays(diasAtras));
            }
            else
            {
                diasAtras = -1 * antiguedad;
                //return fecha.AddDays(diasAtras).ToString("dd/MM/yyyy");
            }
            return fecha.AddDays(diasAtras);
        }
        
        //CALCULA LA ANTIGUEDAD A PARTIR DE LA FECHA DADA
        public void generarTablaConsolidadoInicial(DateTime fecha, string nombreTabla, int antiguedadSegunPeriodo,
                                                    List<DIR> dirs)
        {

            List<string[]> listaData = new List<string[]>();
            List<string> elementodata;
            listaDIR = dirs;

            listaEstados = dbEstado.estados.ToList();
            listaTipos = dbTipoTransaccion.tiposTransaccion.ToList();

            try
            {

                int numCols = 0;
                int ano = funciones.calcularAno(fecha);
                string mes = funciones.calcularMes(fecha);
                string semana = funciones.calcularSemana(fecha);
                string stFecha = Constantes.CADENA_VACIA;
                string stAno = Constantes.CADENA_VACIA;
                DateTime auxFecha;

                //DEPENDIENDO DE LA FECHA Y LA ANTIGUEDAD TE CALCULA LA FECHA XORRESPONDIENTE
                auxFecha = calcularFechaXantiguedad(fecha, antiguedadSegunPeriodo, nombreTabla);
                if (Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
                {
                    stAno = funciones.calcularAno(auxFecha).ToString();
                }
                else if (Constantes.IBK_TBL_CONS_MES.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_MES.Equals(nombreTabla))
                {
                    mes = funciones.calcularMes(auxFecha);
                    stAno = funciones.calcularAno(auxFecha).ToString();
                }
                else if (Constantes.IBK_TBL_CONS_SEMANA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_SEMANA.Equals(nombreTabla))
                {
                    semana = funciones.calcularSemana(auxFecha);
                    mes = funciones.calcularMes(auxFecha);
                    stAno = funciones.calcularAno(auxFecha).ToString();
                }
                else
                {
                    stFecha = auxFecha.ToString("dd/MM/yyyy");
                    semana = funciones.calcularSemana(auxFecha);
                    mes = funciones.calcularMes(auxFecha);
                    stAno = funciones.calcularAno(auxFecha).ToString();
                }


                int i = 0;
                int j = 0;
                foreach (DIR d in listaDIR)
                {
                    foreach (TipoTransaccion t in listaTipos)
                    {
                        foreach (EstadoTransaccion e in listaEstados)
                        {
                            elementodata = new List<string>();

                            numCols = agregarElementosGeneralesString(elementodata, stAno, mes, semana, stFecha, j, numCols, nombreTabla);

                            elementodata.Add(d.vcDepartamento); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcProvincia); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcDistrito); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcCodDistrito); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcLocal); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcCodLocal); if (j < 1) { numCols++; }

                            elementodata.Add(t.idCategoria.ToString()); if (j < 1) { numCols++; }
                            elementodata.Add(t.idTipo.ToString()); if (j < 1) { numCols++; }
                            elementodata.Add(e.idEstado.ToString()); if (j < 1) { numCols++; }
                            elementodata.Add("0"); if (j < 1) { numCols++; }

                            elementodata.Add(t.vcTipoMonto); if (j < 1) { numCols++; }
                            elementodata.Add("0"); if (j < 1) { numCols++; }
                            elementodata.Add(d.vcCodDIR); if (j < 1) { numCols++; }

                            if (!Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) && !Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
                            {
                                elementodata.Add(antiguedadSegunPeriodo.ToString()); if (j < 1) { numCols++; }
                            }

                            listaData.Add(elementodata.ToArray());
                            
                            j++;
                        }
                    }
                    i = i + 1;
                    if (i % 15 == 0)
                    {
                        grabarConsolidadoSQL(listaData, numCols, listaData.Count(), nombreTabla);
                        listaData = new List<string[]>();
                    }
                }
                grabarConsolidadoSQL(listaData, numCols, listaData.Count(), nombreTabla);

                string prueba = "rr";
            }
            catch (Exception e)
            {
                string gg = e.Message;
            }

        }

        private int agregarElementosGeneralesString(List<String> elementodata, string stAno, string mes,
                                                    string semana, string stFecha, int contador, int numCols,
                                                    string nombreTabla)
        {
            if (Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
            {
                elementodata.Add(stAno); if (contador < 1) { numCols++; }
            }
            if (Constantes.IBK_TBL_CONS_MES.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_MES.Equals(nombreTabla))
            {
                elementodata.Add(stAno); if (contador < 1) { numCols++; }
                elementodata.Add(mes); if (contador < 1) { numCols++; }
            }
            if (Constantes.IBK_TBL_CONS_SEMANA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_SEMANA.Equals(nombreTabla))
            {
                elementodata.Add(stAno); if (contador < 1) { numCols++; }
                elementodata.Add(mes); if (contador < 1) { numCols++; }
                elementodata.Add(semana); if (contador < 1) { numCols++; }
            }
            if (Constantes.IBK_TBL_CONS_DIA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_DIA.Equals(nombreTabla))
            {
                elementodata.Add(stAno); if (contador < 1) { numCols++; }
                elementodata.Add(mes); if (contador < 1) { numCols++; }
                elementodata.Add(semana); if (contador < 1) { numCols++; }
                elementodata.Add(stFecha); if (contador < 1) { numCols++; }
            }
            return numCols;
        }

        private void grabarConsolidadoSQL(List<string[]> consolidado, int numCols, int numReg, string nombreTabla)
        {
            DataTable dt = new DataTable();

            for (int i = 0; i < numCols; i++)
            {
                dt.Columns.Add(new DataColumn());
            }

            foreach (string[] data in consolidado)
            {
                DataRow row = dt.NewRow();
                row.ItemArray = data;
                dt.Rows.Add(row);
            }

            colocarNombreColumnaDT(dt, nombreTabla);

            using (SqlConnection cn = new SqlConnection(MetodosEstaticos.leerCadenaConexion()))
            {
                cn.Open();
                using (SqlBulkCopy copy = new SqlBulkCopy(cn))
                {
                    mapearDataTable(copy, nombreTabla);
                    copy.BatchSize = numReg;
                    copy.DestinationTableName = nombreTabla;
                    copy.WriteToServer(dt);
                }
                cn.Close();
            }
        }

        private void colocarNombreColumnaDT(DataTable dt, string nombreTabla)
        {
            int j = 0;
            if (Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
            {
                dt.Columns[j].ColumnName = "Ano"; j++;
            }
            if (Constantes.IBK_TBL_CONS_MES.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_MES.Equals(nombreTabla))
            {
                dt.Columns[j].ColumnName = "Ano"; j++;
                dt.Columns[j].ColumnName = "Mes"; j++;
            }
            if (Constantes.IBK_TBL_CONS_SEMANA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_SEMANA.Equals(nombreTabla))
            {
                dt.Columns[j].ColumnName = "Ano"; j++;
                dt.Columns[j].ColumnName = "Mes"; j++;
                dt.Columns[j].ColumnName = "Semana"; j++;
            }
            if (Constantes.IBK_TBL_CONS_DIA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_DIA.Equals(nombreTabla))
            {
                dt.Columns[j].ColumnName = "Ano"; j++;
                dt.Columns[j].ColumnName = "Mes"; j++;
                dt.Columns[j].ColumnName = "Semana"; j++;
                dt.Columns[j].ColumnName = "Dia"; j++;
            }

            dt.Columns[j].ColumnName = "Departamento"; j++;
            dt.Columns[j].ColumnName = "Provincia"; j++;
            dt.Columns[j].ColumnName = "Distrito"; j++;
            dt.Columns[j].ColumnName = "CodDistrito"; j++;
            dt.Columns[j].ColumnName = "NombreLocal"; j++;
            dt.Columns[j].ColumnName = "CodLocal"; j++;
            dt.Columns[j].ColumnName = "IdCategoria"; j++;
            dt.Columns[j].ColumnName = "IdTipoTransaccion"; j++;
            dt.Columns[j].ColumnName = "IdEstadoTransaccion"; j++;
            dt.Columns[j].ColumnName = "CantidadTransacciones"; j++;
            dt.Columns[j].ColumnName = "TipoMonto"; j++;
            dt.Columns[j].ColumnName = "Monto"; j++;
            dt.Columns[j].ColumnName = "CodigoDIR"; j++;
            if (!Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) && !Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
            {
                dt.Columns[j].ColumnName = "unidadAntiguedad"; j++;
            }
        }

        private void mapearDataTable(SqlBulkCopy copy, string nombreTabla)
        {
            if (Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
            {
                copy.ColumnMappings.Add("Ano", "inAno");
            }
            if (Constantes.IBK_TBL_CONS_MES.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_MES.Equals(nombreTabla))
            {
                copy.ColumnMappings.Add("Ano", "inAno");
                copy.ColumnMappings.Add("Mes", "vcMes");
            }
            if (Constantes.IBK_TBL_CONS_SEMANA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_SEMANA.Equals(nombreTabla))
            {
                copy.ColumnMappings.Add("Ano", "inAno");
                copy.ColumnMappings.Add("Mes", "vcMes");
                copy.ColumnMappings.Add("Semana", "vcSemana");
            }
            if (Constantes.IBK_TBL_CONS_DIA.Equals(nombreTabla) || Constantes.BCP_TBL_CONS_DIA.Equals(nombreTabla))
            {
                copy.ColumnMappings.Add("Ano", "inAno");
                copy.ColumnMappings.Add("Mes", "vcMes");
                copy.ColumnMappings.Add("Semana", "vcSemana");
                copy.ColumnMappings.Add("Dia", "dtFecha");
            }

            copy.ColumnMappings.Add("Departamento", "vcDepartamento");
            copy.ColumnMappings.Add("Provincia", "vcProvincia");
            copy.ColumnMappings.Add("Distrito", "vcDistrito");
            copy.ColumnMappings.Add("CodDistrito", "vcCodDistrito");
            copy.ColumnMappings.Add("NombreLocal", "vcLocal");
            copy.ColumnMappings.Add("CodLocal", "vcCodLocal");
            copy.ColumnMappings.Add("IdCategoria", "idCategoriaTransaccion");
            copy.ColumnMappings.Add("IdTipoTransaccion", "idTipoTransaccion");
            copy.ColumnMappings.Add("IdEstadoTransaccion", "idEstadoTransaccion");
            copy.ColumnMappings.Add("CantidadTransacciones", "inCantidadTransacciones");
            copy.ColumnMappings.Add("TipoMonto", "vcTipoMonto");
            copy.ColumnMappings.Add("Monto", "ftMonto");
            copy.ColumnMappings.Add("CodigoDIR", "vcCodDir");

            if (!Constantes.IBK_TBL_CONS_ANO.Equals(nombreTabla) && !Constantes.BCP_TBL_CONS_ANO.Equals(nombreTabla))
            {
                copy.ColumnMappings.Add("unidadAntiguedad", "inUnidadAntiguedad");
            }
        }
        
        
    }
}
